package com.antdant.service;

import com.antdant.entity.Course;
import com.antdant.entity.CreateCourse;
import com.antdant.repository.CourseRepository;
import com.antdant.utils.DataUtils;
import com.antdant.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author Lee Yunc
 * @Date 2021/2/26 21:29
 * @Description:
 * @Version 1.0
 */
@Slf4j
@Service
public class CourseService {

    @Resource
    private CourseRepository courseRepository;

    /**
     * 分页查询课程
     *
     * @param pageCurrent
     * @param pageSize
     * @param courseName  课程名称（模糊查询）
     * @return
     */
    public Page<Course> getCourses(Integer pageCurrent, Integer pageSize, String courseName) {
        Sort sort = Sort.by(Sort.Direction.DESC, "studentCount"); //按照人数排序
        Pageable pageable = PageRequest.of(pageCurrent - 1, pageSize, sort);

        return courseRepository.findAll((Specification<Course>) (root, criteriaQuery, criteriaBuilder) -> {
            log.info("首页课程按名字查找：" + courseName);
            Predicate temp = criteriaBuilder.like(root.get("courseName"), "%" + courseName + "%");
            return temp;
        }, pageable);
    }

    /**
     * 按条件返回分页数据(管理员)
     *
     * @param current
     * @param size
     * @param course
     * @return
     */
    public Page<Course> getAllCourse(Integer current, Integer size, Course course) {
        Sort sort = Sort.by(Sort.Direction.DESC, "studentCount"); //按照人数排序
        Pageable pageable = PageRequest.of(current - 1, size, sort);
        return courseRepository.findAll(new Specification<Course>() {
            @Override
            public Predicate toPredicate(Root<Course> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<>();
                if (DataUtils.isNotEmptyStr(course.getCourseName())) {
                    log.info("管理页课程按名字查找：" + course.getCourseName());
                    list.add(criteriaBuilder.like(root.get("courseName"), course.getCourseName()));
                }
                if (course.getType() > 0) {
                    list.add(criteriaBuilder.equal(root.get("type"), course.getType()));
                }
                if (course.getLevel() > 0) {
                    list.add(criteriaBuilder.equal(root.get("level"), course.getLevel()));
                }
                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        }, pageable);
    }

    /**
     * 根据课程id获取课程
     *
     * @param id
     * @return
     */
    public Course getCoursesById(Integer id) {
        return courseRepository.findById(id).orElse(null);
    }

    /**
     * 根据课程类型查找课程
     *
     * @param types
     * @return
     */
    public Page<Course> getCoursesByType(String types) {
        Sort sort = Sort.by(Sort.Direction.DESC, "studentCount"); //按照人数排序
        Pageable pageable = PageRequest.of(0, 9, sort);
        return courseRepository.findAll((Specification<Course>) (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            for (int i = 0; i < types.length(); i++) {
                list.add(criteriaBuilder.equal(root.get("type"), Integer.parseInt(types.substring(i, i + 1))));
            }
            return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
        }, pageable);
    }

    /**
     * 更新课程信息
     *
     * @param course
     * @return
     */
    public Course updateCourseInfo(Course course) {
        return courseRepository.saveAndFlush(course);
    }

    /**
     * 判断当前登录用户是否是该课程的管理员
     *
     * @param userId
     * @param courseId
     * @return
     */
    public boolean isThisManager(Integer userId, Integer courseId) {
        Course course = courseRepository.findById(courseId).orElse(null);
        assert course != null;
        return course.getCourseManagerId() == userId;
    }

    /**
     * 根据课程管理员id（courseManagerId）返回课程id
     *
     * @param courseManagerId
     * @return
     */
    public Integer getCourseIdByCourseManagerId(Integer courseManagerId) {
        Integer id = 0;
        List<Course> list = courseRepository.findAll(new Specification<Course>() {
            @Override
            public Predicate toPredicate(Root<Course> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate temp = criteriaBuilder.equal(root.get("courseManagerId"), courseManagerId);
                return temp;
            }
        });
        if (!CollectionUtils.isEmpty(list)) {
            id = list.get(0).getId();
        }
        return id;
    }

    /**
     * 根据课程管理员id删除课程
     *
     * @param courseManagerId
     * @return
     */
    public boolean deleteCourseByCourseManagerId(Integer courseManagerId) {
        try {
            courseRepository.deleteCourseByCourseManagerId(courseManagerId);
            return true;
        } catch (RuntimeException e) {
            return false;
        }
    }

    /**
     * 通过课程id 找到课程 并使其成员数减一
     *
     * @param courseId
     */
    public void subtractStudentCount(Integer courseId) {
        Course course = courseRepository.findById(courseId).orElse(null);
        assert course != null;
        Integer num = course.getStudentCount() - 1;
        course.setStudentCount(num);
        courseRepository.saveAndFlush(course);
    }

    /**
     * 通过课程id 找到课程 并使其成员数加一
     *
     * @param courseId
     */
    public void addStudentCount(Integer courseId) {
        Course course = courseRepository.findById(courseId).orElse(null);
        assert course != null;
        Integer num = course.getStudentCount() + 1;
        course.setStudentCount(num);
        courseRepository.saveAndFlush(course);
    }


    /**
     * 创建一个新课程
     *
     * @param createCourse
     * @return
     */
    public Course createNewCourse(CreateCourse createCourse) {
        Course course = new Course();
        course.setCourseName(createCourse.getApplyToName());
        course.setStudentCount(1);
        course.setCourseManagerId(createCourse.getApplyFromId());
        course.setType(createCourse.getCourseType());
        course.setContact(createCourse.getContact());
        course.setCreateTime(DateUtils.getNowTime());
        course.setLevel(1);
        return courseRepository.saveAndFlush(course);
    }

}
